package com.blood.modules.pregnancy.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Snowflake;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.blood.core.config.mybatisplus.ICommonServiceImpl;
import com.blood.core.enums.PregnancyStatusEnum;
import com.blood.core.enums.PregnancyUserLabelEnum;
import com.blood.core.resp.GlobalResultStatus;
import com.blood.core.resp.PageResult;
import com.blood.core.resp.ResponseResult;
import com.blood.core.util.DateUtil;
import com.blood.core.util.ObjectAssertUtil;
import com.blood.core.util.bean.BeanUtil;
import com.blood.core.util.bean.ListUtils;
import com.blood.core.util.http.RequestTheadUtils;
import com.blood.modules.pregnancy.dto.req.PregnancyGatherUserPageReq;
import com.blood.modules.pregnancy.dto.req.PregnancyUserPageReq;
import com.blood.modules.pregnancy.dto.req.PregnancyUserReq;
import com.blood.modules.pregnancy.dto.req.PregnancyUserSaveReq;
import com.blood.modules.pregnancy.dto.resp.PregnancyGatherUserPageResp;
import com.blood.modules.pregnancy.dto.resp.PregnancyUserInfoResp;
import com.blood.modules.pregnancy.dto.resp.PregnancyUserPageResp;
import com.blood.modules.pregnancy.mapper.PregnancyUserMapper;
import com.blood.modules.pregnancy.model.PregnancyGatherInfo;
import com.blood.modules.pregnancy.model.PregnancyUser;
import com.blood.modules.pregnancy.service.IPregnancyGatherInfoService;
import com.blood.modules.pregnancy.service.IPregnancyUserService;
import com.blood.modules.system.service.ISysRoleAuthorityService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 孕产用户Service业务层处理
 *
 * @author daoren
 * @date 2022-11-24 11:36:34
 */
@Service
public class PregnancyUserServiceImpl extends ICommonServiceImpl<PregnancyUserMapper, PregnancyUser> implements IPregnancyUserService {
    @Autowired
    private Snowflake snowFlake;
    @Autowired
    private IPregnancyGatherInfoService pregnancyGatherInfoService;
    @Autowired
    private ISysRoleAuthorityService sysRoleAuthorityService;
    @Override
    public ResponseResult<PageResult<PregnancyUserPageResp>> pageList(PregnancyUserPageReq req) {
        PageResult<PregnancyUserPageResp> pageResult = PageResult.create(req.getPageNo(), req.getPageSize());
        QueryWrapper<PregnancyUser> queryWrapper = new QueryWrapper<>();
        sysRoleAuthorityService.queryDataAuthority(queryWrapper);
        LambdaQueryWrapper<PregnancyUser> qw = queryWrapper.lambda();
        if (StringUtils.isNotBlank(req.getName())) {
            qw.like(PregnancyUser::getName, req.getName());
        }
        if (StringUtils.isNotBlank(req.getRemake())) {
            qw.like(PregnancyUser::getRemake, req.getRemake());
        }
        if (null != req.getDueDate()) {
            qw.eq(PregnancyUser::getDueDate, req.getDueDate());
        }
        if (null != req.getGatherStart()) {
            qw.ge(PregnancyUser::getGatherTime, req.getGatherStart());
        }
        if (null != req.getGatherEnd()) {
            qw.le(PregnancyUser::getGatherTime, req.getGatherEnd());
        }
        if (StringUtils.isNotBlank(req.getHospitalNumber())) {
            qw.eq(PregnancyUser::getHospitalNumber, req.getHospitalNumber());
        }
        if (null != req.getStatus()) {
            qw.eq(PregnancyUser::getStatus, req.getStatus());
        }
        if (CollectionUtil.isNotEmpty(req.getStatusList())) {
            qw.in(PregnancyUser::getStatus, req.getStatusList());
        }
        if (StringUtils.isNotBlank(req.getPhone())) {
            qw.like(PregnancyUser::getPhone, req.getPhone());
        }
        if (CollectionUtil.isNotEmpty(req.getStatusList()) && PregnancyStatusEnum.DISCHARGED.getValue().equals(req.getStatusList().get(0))) {
            qw.orderByDesc(PregnancyUser::getUpdateTime);
        } else {
            qw.orderByAsc(PregnancyUser::getGatherTime);
        }

        IPage<PregnancyUser> iPage = baseMapper.selectPage(new Page<>(req.getPageNo(), req.getPageSize()), qw);
        if (iPage.getRecords().size() > 0) {
            List<PregnancyGatherInfo> gatherInfoList = Collections.emptyList();
            //查看往期孕妇
            if (CollectionUtil.isNotEmpty(req.getStatusList()) && PregnancyStatusEnum.DISCHARGED.getValue().equals(req.getStatusList().get(0)) ) {
                List<String> idList = iPage.getRecords().stream().map(m -> m.getId()).collect(Collectors.toList());
                gatherInfoList = pregnancyGatherInfoService.queryList(idList);
            }
            List<PregnancyUserPageResp> respList = new ArrayList<>(iPage.getRecords().size());
            for (PregnancyUser record : iPage.getRecords()) {
                PregnancyUserPageResp resp = new PregnancyUserPageResp();
                resp.setId(record.getId());
                resp.setName(record.getName());
                resp.setPhone(record.getPhone());
                resp.setHospitalNumber(record.getHospitalNumber());
                resp.setDueDate(record.getDueDate());
                resp.setDilatancy(record.getDilatancy());
                resp.setDecline(record.getDecline());
                resp.setGatherTime(record.getGatherTime());
                resp.setStatus(record.getStatus());
                resp.setRemake(record.getRemake());
                if (CollectionUtil.isNotEmpty(gatherInfoList)) {
                    resp.setNormalNumber(gatherInfoList.stream().filter(f -> f.getPregnancyId().equals(record.getId()) && PregnancyStatusEnum.NORMAL.getValue().equals(f.getAbnormalStatus()))
                            .findFirst()
                            .orElse(new PregnancyGatherInfo()).getNumber());
                    resp.setEarlyNumber(gatherInfoList.stream().filter(f -> f.getPregnancyId().equals(record.getId()) && PregnancyStatusEnum.EARLY.getValue().equals(f.getAbnormalStatus()))
                            .findFirst()
                            .orElse(new PregnancyGatherInfo()).getNumber());
                    resp.setRiskNumber(gatherInfoList.stream().filter(f -> f.getPregnancyId().equals(record.getId()) && PregnancyStatusEnum.RISK.getValue().equals(f.getAbnormalStatus()))
                            .findFirst()
                            .orElse(new PregnancyGatherInfo()).getNumber());
                    resp.setTotalNumber(resp.getNormalNumber()+resp.getEarlyNumber()+resp.getRiskNumber());
                }

                respList.add(resp);
            }
            ListUtils.copyProperties(iPage.getRecords(), PregnancyUserPageResp.class);
            return GlobalResultStatus.SUCCESS.toResult().response(pageResult.data(iPage.getTotal(), respList));
        }
        return GlobalResultStatus.SUCCESS.toResult().response(pageResult.data(0, Collections.emptyList()));
    }

    @Override
    public PageResult<PregnancyGatherUserPageResp> gatherUserPageList(PregnancyGatherUserPageReq req) {
        PageResult<PregnancyGatherUserPageResp> pageResult = PageResult.create(req.getPageNo(), req.getPageSize());
        QueryWrapper<PregnancyUser> queryWrapper = new QueryWrapper<>();
        sysRoleAuthorityService.queryDataAuthority(queryWrapper);
        LambdaQueryWrapper<PregnancyUser> qw = queryWrapper.lambda();
        if (StringUtils.isNotBlank(req.getName())) {
            qw.like(PregnancyUser::getName, req.getName());
        }
        if (null != req.getGatherStart()) {
            qw.ge(PregnancyUser::getGatherTime, req.getGatherStart());
        }
        if (null != req.getGatherEnd()) {
            qw.lt(PregnancyUser::getGatherTime, req.getGatherEnd());
        }

        if (null != req.getStatus()) {
            qw.eq(PregnancyUser::getStatus, req.getStatus());
        }

        qw.orderByAsc(PregnancyUser::getGatherTime);
        IPage<PregnancyUser> iPage = baseMapper.selectPage(new Page<>(req.getPageNo(), req.getPageSize()), qw);
        if (iPage.getRecords().size() > 0) {
            List<PregnancyGatherUserPageResp> respList = new ArrayList<>(iPage.getRecords().size());
            Date date = new Date();
            for (PregnancyUser record : iPage.getRecords()) {
                PregnancyGatherUserPageResp resp = new PregnancyGatherUserPageResp();
                resp.setId(record.getId());
                resp.setGatherId(record.getGatherId());
                resp.setGatherTime(record.getGatherTime());
                resp.setName(record.getName());
                resp.setStatus(record.getStatus());
                Date gatherTime = null != record.getGatherTime() ? record.getGatherTime() : record.getCreateTime();
                if (DateUtil.dateHour(gatherTime, date) >= 2L) {
                    if (PregnancyStatusEnum.NORMAL.getValue().equals(req.getStatus())) {
                        resp.setLabel(PregnancyUserLabelEnum.UN_GATHER.getValue());
                    }
                    if (PregnancyStatusEnum.getAbnormalStatusList().contains(req.getStatus())) {
                        resp.setLabel(PregnancyUserLabelEnum.UN_DISPOSED.getValue());
                    }
                }
                respList.add(resp);
            }
            return pageResult.data(iPage.getTotal(), respList);
        }
        return pageResult.data(0, Collections.emptyList());
    }

    @Override
    public List<PregnancyUser> queryList(PregnancyUserReq req) {
        QueryWrapper<PregnancyUser> queryWrapper = new QueryWrapper<>();
        sysRoleAuthorityService.queryDataAuthority(queryWrapper);
        return baseMapper.selectList(queryWrapper.lambda()
                .ne(PregnancyUser::getStatus, PregnancyStatusEnum.DISCHARGED.getValue())
                .like(PregnancyUser::getName, req.getName())
                .eq(PregnancyUser::isDeleteFlag, false)
        );
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> saveInfo(PregnancyUserSaveReq req) {
        String id = snowFlake.nextIdStr();
        PregnancyUser saveInfo = new PregnancyUser();
        BeanUtil.copyProperties(req, saveInfo);
        saveInfo.setId(id);
        saveInfo.setHospitalTime(new Date());
        saveInfo.setOrgId(RequestTheadUtils.getOrgId());
        saveInfo.setCreateBy(RequestTheadUtils.getUserId());
        baseMapper.insert(saveInfo);
        return GlobalResultStatus.SUCCESS.toResult().responseEmptyBody();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> updateInfo(PregnancyUserSaveReq req) {
        PregnancyUser queryInfo = super.findById(req.getId());
        ObjectAssertUtil.objectIsNull(queryInfo, "未获取到详细信息!");
        BeanUtil.copyProperties(req, queryInfo);
        queryInfo.setUpdateBy(RequestTheadUtils.getUserId());
        baseMapper.updateById(queryInfo);
        return GlobalResultStatus.SUCCESS.toResult().responseEmptyBody();
    }

    @Override
    public ResponseResult<PregnancyUserInfoResp> findDetailById(String id) {
        PregnancyUser queryInfo = super.findById(id);
        ObjectAssertUtil.objectIsNull(queryInfo, "详细信息不存在!");
        return GlobalResultStatus.SUCCESS.toResult().response(BeanUtil.copyProperties(queryInfo, PregnancyUserInfoResp.class));
    }
}
